using System;
using Castle.ActiveRecord;
using Castle.Components.Validator;
using System.Collections.Generic;
using NHibernate.Criterion;
using NHibernate;
using System.Linq;

namespace DecisionMaking.Domain
{
	[ActiveRecord]
	public class Cue : ActiveRecordValidationBase<Cue>
	{
		private IList<CueAttributeValue> attributeValues = new List<CueAttributeValue>();
		
		public Cue ()
		{
		}
				
	    [PrimaryKey(PrimaryKeyType.Native)]
	    public int Id {set; get;}	
		
		[BelongsTo(NotNull = true, UniqueKey = "uix_cue_name")]
		public Environment Environment {set; get;}
		
		[Property(NotNull = true, UniqueKey = "uix_cue_name"), ValidateLength(2, 50)]
		public string Name {set; get;}		
		
		[HasMany(typeof(CueAttributeValue), Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Inverse = true)]
		public IList<CueAttributeValue> AttributeValues  
		{
			get {return attributeValues;}
			set {attributeValues = value;}
		}

		/// <summary>
		/// Returns the value for the specified attribute or null if not found
		/// </summary>
		/// <param name="cueAttribute">
		/// A <see cref="CueAttribute"/>
		/// </param>
		/// <returns>
		/// A <see cref="System.Nullable<System.Double>"/>
		/// </returns>
		public double? GetAttributeValue(CueAttribute cueAttribute)
		{
			var q = (from a in AttributeValues where a.CueAttribute.Equals(cueAttribute) select a.Value);
			return q.Single();
		}
		
		/// <summary>
		/// Returns a list of Cues from the specified Environment, fetching the attribute values along with them 
		/// </summary>
		/// <param name="environmentId">
		/// A <see cref="System.Int32"/>
		/// </param>
		/// <returns>
		/// A <see cref="IList<Cue>"/>
		/// </returns>
		public static IList<Cue> FindByEnvironmentId(int environmentId)
		{
			DetachedCriteria criteria = DetachedCriteria.For(typeof(Cue));
			
			criteria.CreateCriteria("Environment").Add(Restrictions.IdEq(environmentId));
			
			return FindAll(criteria);
		}
		
		public override bool Equals (object obj)
		{
			if (obj == null)
				return false;
			if (ReferenceEquals (this, obj))
				return true;
			if (obj.GetType () != typeof(Cue))
				return false;
			DecisionMaking.Domain.Cue other = (DecisionMaking.Domain.Cue)obj;
			return Id == other.Id;
		}


		public override int GetHashCode ()
		{
			unchecked {
				return Id.GetHashCode ();
			}
		}

	}
		
}

